package utils

import (
	"bytes"
	"fmt"
	"os"
	"os/exec"
	"path/filepath"
	"runtime"
	"strconv"
	"strings"
	"syscall"
)

func CreateDirIfNotExist(filePath string) {
	dir := filepath.Dir(filePath)
	err := os.MkdirAll(dir, 0755)
	if err != nil {
		fmt.Println("创建目录失败:", err)
		return
	}
	fmt.Println("目录已创建:", dir)
}

func GetJarPIDWithJPS(jarPath string) (int, error) {
	cmd := exec.Command("jps", "-l")
	var out bytes.Buffer
	cmd.Stdout = &out
	err := cmd.Run()
	if err != nil {
		return 0, fmt.Errorf("failed to execute jps command: %v", err)
	}

	lines := strings.Split(out.String(), "\n")
	for _, line := range lines {
		if strings.Contains(line, jarPath) {
			fields := strings.Fields(line)
			if len(fields) > 0 {
				pid, err := strconv.Atoi(fields[0])
				if err == nil {
					return pid, nil
				}
			}
		}
	}

	return 0, fmt.Errorf("no process found for JAR: %s", jarPath)
}

func KillProcessByPID(pid int) error {
	// 查找进程
	proc, err := os.FindProcess(pid)
	if err != nil {
		return fmt.Errorf("failed to find process with PID %d: %v", pid, err)
	}

	// 根据操作系统发送终止信号
	switch runtime.GOOS {
	case "windows":
		// Windows 使用 taskkill 命令强制终止进程
		cmd := exec.Command("taskkill", "/PID", fmt.Sprint(pid), "/F")
		if err := cmd.Run(); err != nil {
			return fmt.Errorf("failed to kill process %d on Windows: %v", pid, err)
		}
	case "linux", "darwin", "unix":
		// Linux/Unix 使用 SIGTERM 优雅终止，失败则尝试 SIGKILL
		if err := proc.Signal(syscall.SIGTERM); err != nil {
			// 如果 SIGTERM 失败，尝试 SIGKILL
			if err := proc.Signal(syscall.SIGKILL); err != nil {
				return fmt.Errorf("failed to kill process %d on %s: %v", pid, runtime.GOOS, err)
			}
		}
	default:
		return fmt.Errorf("unsupported platform: %s", runtime.GOOS)
	}

	// 验证进程是否已终止（可选）
	_, err = os.FindProcess(pid)
	if err == nil {
		// 进程仍然存在，可能是因为终止未完成
		return fmt.Errorf("process %d may still be running", pid)
	}

	return nil
}
